/**********************************Copyright (c)**********************************
**                       版权所有 (C), 2015-2020, 涂鸦科技
**
**                             http://www.tuya.com
**
*********************************************************************************/
/**
 * @file    protocol.h
 * @author  涂鸦综合协议开发组
 * @version v1.0.5
 * @date    2021.10.19
 * @brief                
 *                       *******非常重要，一定要看哦！！！********
 *          1. 用户在此文件中实现数据下发/上报功能
 *          2. DP的ID/TYPE及数据处理函数都需要用户按照实际定义实现
 *          3. 当开始某些宏定义后需要用户实现代码的函数内部有#err提示,完成函数后请删除该#err
 */

/****************************** 免责声明 ！！！ *******************************
由于MCU类型和编译环境多种多样，所以此代码仅供参考，用户请自行把控最终代码质量，
涂鸦不对MCU功能结果负责。
******************************************************************************/

#ifndef __PROTOCOL_H_
#define __PROTOCOL_H_

#include "tuya_type.h"

/******************************************************************************
                            用户相关信息配置
******************************************************************************/
/******************************************************************************
                            1:修改产品信息                
******************************************************************************/
#define PRODUCT_KEY "dp5a0ldywgckc4yw"    //开发平台创建产品后生成的16位字符产品唯一标识

#define MCU_VER "1.0.0"                                 //用户的软件版本,用于MCU固件升级,MCU升级版本需修改

/******************************************************************************
                        1.5:模组配置模式选择
模块工作方式选择，只能三选一，推荐使用防误触模式
******************************************************************************/
#define CONFIG_MODE_DEFAULT             0           //默认工作模式
#define CONFIG_MODE_LOWPOWER            1           //安全模式(低功耗配网方式)
#define CONFIG_MODE_SPECIAL             2           //防误触模式(特殊配网方式)

#define CONFIG_MODE                 CONFIG_MODE_SPECIAL  //选择配置模式

/* 设置低功耗配网方式和特殊配网方式的配网模式打开时间，该宏处于注释状态将按三分钟处理
   可以支持的设置数据范围: 3~10 分钟 */
//#define CONFIG_MODE_DELAY_TIME          10          //配网模式打开时间(单位:分钟)

/* 选择smart模式和热点配网模式，该宏都注释将保持smart模式和热点配网模式相互切换 */
//#define CONFIG_MODE_CHOOSE              0           //模组同时支持热点连接配网和EZ配网,对应配网状态0x06
//#define CONFIG_MODE_CHOOSE              1           //仅只有热点配网模式

/* 启用模组的红外功能并告知模组红外的收发脚使用那些IO口，没有该字段红外能力默认关闭 */
//#define ENABLE_MODULE_IR_FUN                        //启用模组的红外功能
#ifdef ENABLE_MODULE_IR_FUN
#define MODULE_IR_PIN_TX                5           //红外发送脚
#define MODULE_IR_PIN_RX                12          //红外接收脚
#endif

/* 模组是否开启保持长连接的低功耗模式，没有该字段低功耗模式默认关闭 */
//#define LONG_CONN_LOWPOWER              0           //关闭低功耗模式
//#define LONG_CONN_LOWPOWER              1           //打开低功耗模式

/******************************************************************************
                          2:MCU是否需要支固件升级
如需要支持MCU固件升级,请开启该宏
MCU可调用mcu_api.c文件内的mcu_firm_update_query()函数获取当前MCU固件更新情况
                        ********WARNING!!!**********
当前接收缓冲区为关闭固件更新功能的大小,固件升级包可选择，默认256字节大小
如需要开启该功能,串口接收缓冲区会变大
******************************************************************************/
#define         SUPPORT_MCU_FIRM_UPDATE                 //开启MCU固件升级功能(默认关闭)
/*  固件包大小选择  */
#ifdef SUPPORT_MCU_FIRM_UPDATE
#define PACKAGE_SIZE                   0        //包大小为256字节
//#define PACKAGE_SIZE                   1        //包大小为512字节
//#define PACKAGE_SIZE                   2        //包大小为1024字节
#endif

/******************************************************************************
                         3:定义收发缓存:
                    如当前使用MCU的RAM不够,可修改为24
******************************************************************************/
#ifndef SUPPORT_MCU_FIRM_UPDATE
#define WIFI_UART_RECV_BUF_LMT          16              //串口数据接收缓存区大小,如MCU的RAM不够,可缩小
#define WIFI_DATA_PROCESS_LMT           24              //串口数据处理缓存区大小,根据用户DP数据大小量定,必须大于24
#else
#define WIFI_UART_RECV_BUF_LMT          128             //串口数据接收缓存区大小,如MCU的RAM不够,可缩小

/*  请在此处选择合适的mcu升级缓存大小（根据上面固件包选择大小来选择开启多大的mcu升级缓存） */
#define WIFI_DATA_PROCESS_LMT           300               //固件升级缓冲区,需大缓存,如单包大小选择256，则缓存必须大于260
//#define WIFI_DATA_PROCESS_LMT           600             //固件升级缓冲区,需大缓存,如单包大小选择512，则缓存必须大于520
//#define WIFI_DATA_PROCESS_LMT           1200            //固件升级缓冲区,需大缓存,如单包大小选择1024，则缓存必须大于1030
#endif
#define WIFIR_UART_SEND_BUF_LMT         48              //根据用户DP数据大小量定,必须大于48

/******************************************************************************
                        4:定义模块工作方式
模块自处理:
          wifi指示灯和wifi复位按钮接在wifi模块上(开启WIFI_CONTROL_SELF_MODE宏)
          并正确定义WF_STATE_KEY和WF_RESET_KEY
MCU自处理:
          wifi指示灯和wifi复位按钮接在MCU上(关闭WIFI_CONTROL_SELF_MODE宏)
          MCU在需要处理复位wifi的地方调用mcu_api.c文件内的mcu_reset_wifi()函数,并可调用mcu_get_reset_wifi_flag()函数返回复位wifi结果
          或调用设置wifi模式mcu_api.c文件内的mcu_set_wifi_mode(WIFI_CONFIG_E mode)函数,并可调用mcu_get_wifi_work_state()函数返回设置wifi结果
******************************************************************************/
// #define         WIFI_CONTROL_SELF_MODE                      //wifi自处理按键及LED指示灯;如为MCU外界按键/LED指示灯请关闭该宏
#ifdef          WIFI_CONTROL_SELF_MODE                      //模块自处理
    #define     WF_STATE_KEY            14                  //wifi模块状态指示按键，请根据实际GPIO管脚设置
    #define     WF_RESERT_KEY           0                   //wifi模块重置按键，请根据实际GPIO管脚设置
#endif


/******************************************************************************
                      5:MCU是否需要支持校时功能
如需要请开启该宏,并在Protocol.c文件内mcu_write_rtctime实现代码
mcu_write_rtctime内部有#err提示,完成函数后请删除该#err
mcu在wifi模块正确联网后可调用mcu_get_system_time()函数发起校时功能
******************************************************************************/
#define         SUPPORT_MCU_RTC_CHECK                //开启校时功能

/******************************************************************************
                      6:MCU是否需要支持wifi功能测试
如需要请开启该宏,并且mcu在需要wifi功能测试处调用mcu_api.c文件内mcu_start_wifitest
并在protocol.c文件wifi_test_result函数内查看测试结果,
wifi_test_result内部有#err提示,完成函数后请删除该#err
******************************************************************************/
#define         WIFI_TEST_ENABLE                //开启WIFI产测功能（扫描指定路由）

/******************************************************************************
                      7:MCU是否支持wifi模块固件升级              
这里 WIFI 模块的电源通断是由 MCU 去控制的，这里当我们 MCU 需要去升级 WIFI
模块的固件便可以通过下面的命令去拉去最新固件。MCU 主板根据 WIFI 模块的回复包决
定是否需要给 WIFI 模块断电。这里 MCU 当发送 0a 命令等待 5S 没有收到相关回复便把
WIFI 模块断电。当模块回复正在更新固件这里 MCU 也需要起一个定时当处于正在更新固
件超过 60S 没有收到固件升级成功，也强制认为固件升级失败给 WIFI 模块断电

如需要支持wifi模块固件升级,请开启该宏
******************************************************************************/
#define         WIFI_MODULE_UPDATE                 //开启WIFI模块固件升级

/******************************************************************************
                      8:MCU 是否支持查询当前连接路由的信号强度
如需要请开启该宏。当需要查询当前连接路由的信号强度时，mcu会调用mcu_api.c文件中的qur_router_strenth。
并在protocol_c文件router_strenth_result函数中查看测试结果。
router_strenth_result内部有#err提示,完成函数后请删除该#err.
******************************************************************************/
#define         WIFI_QUERY_ROUTE_RSSI             //开启查询当前连接路由的信号强度

/******************************************************************************
                      9:MCU是否支持获取dp缓存指令
对于某些带设置性或控制功能的传感器，需要新增 dp 下发功能。当在设备离线时，面板
有指令下发，这条指令会缓存在云端，等待设备主动获取。缓存命令的为增量方式，对于
已经获取过的命令，再次获取时不会下发

如需要支持获取dp缓存指令,请开启该宏
******************************************************************************/
#define         DO_CACHE_SUPPORT                   //获取dp缓存指令





/******************************************************************************
                        1:dp数据点序列号重新定义
          **此为自动生成代码,如在开发平台有相关修改请重新下载MCU_SDK**         
******************************************************************************/
//原水TDS(只上报)
//备注:
#define DPID_TDS_IN 1
//温度(只上报)
//备注:
#define DPID_TEMP_CURRENT 2
//电池电量状态(只上报)
//备注:
#define DPID_BATTERY_STATE 6
//电池电量(只上报)
//备注:
#define DPID_BATTERY_PERCENTAGE 7
//防拆报警(只上报)
//备注:
#define DPID_TAMPER_ALARM 8
//传感器探头(只上报)
//备注:
#define DPID_SENSOR_PROBE 9
//pH(只上报)
//备注:
#define DPID_PH 10
//电导率(只上报)
//备注:
#define DPID_CONDUCTIVITY_VALUE 11
//ORP(只上报)
//备注:
#define DPID_ORP_VALUE 12
//余氯(只上报)
//备注:
#define DPID_CL_VALUE 13
//UV(只上报)
//备注:
#define DPID_UV_VALUE 14
//LSI(可下发可上报)
//备注:
#define DPID_LSI_VALUE 15
//CA(可下发可上报)
//备注:
#define DPID_CA_VALUE 16
//TA(可下发可上报)
//备注:
#define DPID_TA_VALUE 17
//校准(可下发可上报)
//备注:
#define DPID_CALIBRATION 18
//校准结果(只上报)
//备注:
#define DPID_CALIBRATION_RESULT 19
//校准补偿(可下发可上报)
//备注:
#define DPID_CALIBRATION_COMP 20
//报警开关(可下发可上报)
//备注:
#define DPID_ALARM_SWITCH 21
//体积单位(可下发可上报)
//备注:
#define DPID_UNIT_SWITCH 23
//出厂设置(可下发可上报)
//备注:
#define DPID_FACTORY_RESET 24



/**
 * @brief  串口发送数据
 * @param[in] {value} 串口要发送的1字节数据
 * @return Null
 * @note   请在此函数中填写MCU串口发送功能，并将接收到的数据作为参数传递给串口发送函数
 */
void uart_transmit_output(u8 value);

/**
 * @brief  系统所有dp点信息上传,实现APP和muc数据同步
 * @param  Null
 * @return Null
 * @note   此函数SDK内部需调用，MCU必须实现该函数内数据上报功能，包括只上报和可上报可下发型数据
 */
void all_data_update(void);

/**
 * @brief  所有DP数据使用0x07(WIFI_TEST_CMD)逐条上报
 * @param  Null
 * @return Null
 * @note   当WiFi模块发送0x08命令(STATE_RC_UPLOAD_CMD)请求时调用此函数
 */
void all_data_for_wifi_test(void);

/**
 * @brief  记录型数据组合上报
 * @param[in] {time} 时间数据长度7,首字节表示是否传输标志位，其余依次为年、月、日、时、分、秒
 * @param[in] {dp_bool}   bool型dpid号
 * @param[in] {v_bool}    bool型dp对应值
 * @param[in] {dp_enum}   enum型dpid号
 * @param[in] {v_enum}    enum型dp对应值
 * @param[in] {dp_value}  value型dpid号
 * @param[in] {v_value}   value型dp对应值
 * @param[in] {dp_string} string型dpid号
 * @param[in] {v_string}  string型dp对应值
 * @param[in] {len}       string长度
 * @return SUCCESS(1) or ERROR(0)
 * @note   当需要上报记录数据时调用该函数
 */
u8 dp_record_combine_update(u8 time[],
                                       u8 dp_bool,u8 v_bool,
                                       u8 dp_enum,u8 v_enum,
                                       u8 dp_value,u8 v_value,
                                       u8 dp_string,u8 v_string[],u8 len);

/**
 * @brief  dp下发处理函数
 * @param[in] {dpid} dpid 序号
 * @param[in] {value} dp数据缓冲区地址
 * @param[in] {length} dp数据长度
 * @return dp处理结果
 * -           0(ERROR): 失败
 * -           1(SUCCESS): 成功
 * @note   该函数用户不能修改
 */
u8 dp_download_handle(u8 dpid,const u8 value[], u16 length);

/**
 * @brief  获取所有dp命令总和
 * @param[in] Null
 * @return 下发命令总和
 * @note   该函数用户不能修改
 */
u8 get_download_cmd_total(void);

#ifdef SUPPORT_MCU_RTC_CHECK
/**
 * @brief  MCU校对本地RTC时钟
 * @param[in] {time} 获取的时间数据
 * @return 无
 * @note   MCU需要自行实现该功能
 */
void mcu_write_rtctime(u8 time[]);
#endif

#ifdef WIFI_TEST_ENABLE
/**
 * @brief  wifi功能测试反馈
 * @param[in] {result} wifi功能测试结果
 * @ref       0: 失败
 * @ref       1: 成功
 * @param[in] {rssi} 测试成功表示wifi信号强度/测试失败表示错误类型
 * @return Null
 * @note   MCU需要自行实现该功能
 */
void wifi_test_result(u8 result,u8 rssi);
#endif

#ifdef WIFI_MODULE_UPDATE
/**
 * @brief  请求 WIFI 模块固件升级结果返回
 * @param[in] {result} 请求 WIFI 模块固件升级结果;
 * @ref    0x00(开始检测固件更新) 不可断电
 * @ref    0x01(已经是最新固件) 断电
 * @ref    0x02(正在更新固件) 不可断电
 * @ref    0x03(固件更新成功) 断电
 * @ref    0x04(固件更新失败) 断电
 * @return 无
 * @note   MCU需要自行实现该功能
 */
void qur_module_ug_result(u8 result);
#endif

#ifdef WIFI_QUERY_ROUTE_RSSI
/**
 * @brief  查询当前连接路由器信号强度
 * @param[in] {result} wifi功能测试结果;0:失败/1:成功
 * @param[in] {rssi} 测试成功表示wifi信号强度/测试失败表示错误类型
 * @return 无
 * @note   MCU需要自行实现该功能
 */
void router_strenth_result(u8 result,u8 rssi);
#endif

#ifdef SUPPORT_MCU_FIRM_UPDATE
/**
 * @brief  请求 MCU 固件升级结果返回
 * @param[in] {result} 结果返回
 * @return 无
 * @note   MCU需要自行实现该功能
 */
void qur_ug_result(u8 result);

/**
 * @brief  升级包大小选择
 * @param[in] {package_sz} 升级包大小
 * @ref           0x00: 256byte (默认)
 * @ref           0x01: 512byte
 * @ref           0x02: 1024byte
 * @return 无
 * @note   MCU需要自行实现该功能
 */
void upgrade_package_choose(u8 package_sz);

/**
 * @brief  MCU固件升级数据处理
 * @param[in] {value} 固件缓冲区
 * @param[in] {position} 当前数据包在于固件位置
 * @param[in] {length} 当前固件包长度(固件包长度为0时,表示固件包发送完成)
 * @return 无
 * @note   MCU需要自行实现该功能
 */
u8 mcu_firm_update_handle(const u8 value[],u32 position,u16 length);
#endif



#endif

